package joq.server;

import java.io.IOException;
import java.nio.ByteBuffer;
import java.nio.channels.ClosedChannelException;
import java.nio.channels.SocketChannel;
import java.nio.charset.Charset;
import java.nio.charset.CharsetDecoder;

public class Request
{
    private ByteBuffer buffer;
    private CharsetDecoder decoder;
    private StringBuilder request;
    private Message message;

    Request(Charset charset)
    {
	buffer = ByteBuffer.allocate(512);
	decoder = charset.newDecoder();
	request = new StringBuilder();
	message = null;
    }

    /**
     * Reads as many bytes as are available from a client socket into the
     * Request's internal buffer and returns the total number of bytes
     * read. Returns true when the end of stream is reached (meaning that the
     * client transmission is over).
     */
    public boolean read(SocketChannel client) throws IOException,
						     ClosedChannelException,
						     ProtocolError
    {
	int bytesRead;

	do {
	    buffer.clear();
	    if ((bytesRead = client.read(buffer)) > 0) {
		buffer.flip();
		request.append(decoder.decode(buffer).toString());
	    }
	} while (bytesRead > 0);

	if (bytesRead == -1)
	    throw new ClosedChannelException();

	if (bytesRead == 0)
	    message = MessageProtocol.decode(request.toString());

	return bytesRead == 0;
    }

    /**
     * Parses the request body.
     * @return
     */
    public Message getMessage()
    {
	return message;
    }
}
